package com.xjy.web.controller.system;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Arrays;
import java.util.Date;

import lombok.RequiredArgsConstructor;

import javax.transaction.Transactional;
import javax.validation.constraints.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.xjy.common.annotation.RepeatSubmit;
import com.xjy.common.annotation.Log;
import com.xjy.common.core.controller.BaseController;
import com.xjy.common.core.domain.AjaxResult;
import com.xjy.common.enums.BusinessType;
import com.xjy.common.exception.CustomException;
import com.xjy.system.domain.vo.SysDepositBackVo;
import com.xjy.system.domain.vo.SysDepositUpdateVo;
import com.xjy.system.domain.vo.SysDepositVo;
import com.xjy.system.repository.SysContractResultRepository;
import com.xjy.system.repository.SysDepositBackRepository;
import com.xjy.system.repository.SysDepositRepository;
import com.xjy.system.repository.SysPayaccountRepository;
import com.xjy.system.repository.SysStaffRepository;
import com.xjy.system.repository.SysTransactionUnitRepository;
import com.xjy.system.domain.bo.SysDepositUpdateQueryBo;
import com.xjy.system.domain.SysDeposit;
import com.xjy.system.domain.SysDepositBack;
import com.xjy.system.domain.SysPayaccount;
import com.xjy.system.domain.SysStaff;
import com.xjy.system.domain.bo.SysDepositUpdateAddBo;
import com.xjy.system.domain.bo.SysDepositUpdateEditBo;
import com.xjy.system.service.ISysDepositUpdateService;
import com.xjy.system.service.ProductHelpService;
import com.xjy.common.utils.poi.ExcelUtil;
import com.xjy.common.core.page.TableDataInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 押金变更信息Controller
 *
 * @author zc
 * @date 2022-02-17
 */
@Api(value = "押金变更信息控制器", tags = {"押金变更信息管理"})
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@RestController
@RequestMapping("/system/SysDepositUpdate")
public class SysDepositUpdateController extends BaseController {

    private final ISysDepositUpdateService iSysDepositUpdateService;

	@Autowired
	private SysDepositBackRepository sysDepositBackRepository;
	
	@Autowired
	private SysDepositRepository sysDepositRepository;

	@Autowired
	private ProductHelpService productHelpService; 
	
	@Autowired
	private SysStaffRepository sysStaffRepository;//员工
	
	@Autowired
	private SysTransactionUnitRepository sysTransactionUnitRepository;//往来
	
	@Autowired
	private SysPayaccountRepository sysPayaccountRepository;//账户
	
	
    @GetMapping("/list/{id:\\d+}")
    public Page<SysDepositBackVo> list(Pageable page,@PathVariable long id) {
    	 Page<SysDepositBack> result = this.sysDepositBackRepository.findAllByDepId(id, page);
    	//经办人
		Map<Long, String> staffMap = this.sysStaffRepository.findAllById(result.get().map(SysDepositBack::getDepHandlerId).collect(Collectors.toSet())).stream().collect(Collectors.toMap(SysStaff::getStaffId,SysStaff::getStaffName));
		//帐户
		Map<Long, SysPayaccount> sysPay = this.sysPayaccountRepository.findAllById(result.get().map(SysDepositBack::getDepPayaccountId).collect(Collectors.toSet())).stream().collect(Collectors.toMap(a->a.getId(), a->a));
		//收取或支付方，往来
		Map<Long,String> sysTran = this.sysTransactionUnitRepository.findAllById(result.get().map(a->a.getDepPaiorId()).collect(Collectors.toSet())).stream().collect(Collectors.toMap(a->a.getId(), a->a.getName()));
		List<SysDepositBackVo> list = result.get().map(a->{SysDepositBackVo b = new SysDepositBackVo(); BeanUtils.copyProperties(a, b);return b;}).collect(Collectors.toList());
    	list.forEach(v->{
    		v.setHandle(staffMap.get(v.getDepHandlerId()));
    		v.setTrans(sysTran.get(v.getDepPaiorId()));
			if(sysPay.containsKey(v.getDepPayaccountId())) {
				SysPayaccount sp = sysPay.get(v.getDepPayaccountId());
				v.setBlank(sp.getAccountBank());
				v.setBlankName(sp.getAccountName());
				v.setBlankNo(sp.getAccountPhone());
			}
		});
    	return new PageImpl<>(list, page, result.getTotalElements());
    }
    
    /**
     * 查询押金变更信息列表
     */
    @ApiOperation("查询押金变更信息列表")
    @PreAuthorize("@ss.hasPermi('system:SysDepositUpdate:list')")
    @GetMapping("/list")
    public TableDataInfo<SysDepositUpdateVo> list(@Validated SysDepositUpdateQueryBo bo) {
        return iSysDepositUpdateService.queryPageList(bo);
    }

    /**
     * 导出押金变更信息列表
     */
    @ApiOperation("导出押金变更信息列表")
    @PreAuthorize("@ss.hasPermi('system:SysDepositUpdate:export')")
    @Log(title = "押金变更信息", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult<SysDepositUpdateVo> export(@Validated SysDepositUpdateQueryBo bo) {
        List<SysDepositUpdateVo> list = iSysDepositUpdateService.queryList(bo);
        ExcelUtil<SysDepositUpdateVo> util = new ExcelUtil<SysDepositUpdateVo>(SysDepositUpdateVo.class);
        return util.exportExcel(list, "押金变更信息");
    }

    /**
     * 获取押金变更信息详细信息
     */
    @ApiOperation("获取押金变更信息详细信息")
    @PreAuthorize("@ss.hasPermi('system:SysDepositUpdate:query')")
    @GetMapping("/{id}")
    public AjaxResult<SysDepositUpdateVo> getInfo(@NotNull(message = "主键不能为空")
                                                  @PathVariable("id") Long id) {
        return AjaxResult.success(iSysDepositUpdateService.queryById(id));
    }

    /**
     * 新增押金变更信息
     */
    @ApiOperation("新增押金变更信息")
    @PreAuthorize("@ss.hasPermi('system:SysDepositUpdate:add')")
    @Log(title = "押金变更信息", businessType = BusinessType.INSERT)
    @RepeatSubmit
    @PostMapping()
    @Transactional
    public AjaxResult<Void> add(@Validated @RequestBody SysDepositBack bo) {
    	SysDeposit sd = this.sysDepositRepository.findById(bo.getDepId()).get();
        if(!this.productHelpService.mayUse(sd.getProjId(), bo.getDepTime()))throw new CustomException("项目已在指定时间已结账！不能增加！");
    	bo.setId(null);
    	bo.setPreMoney(sd.getDepBalance());
    	BigDecimal newMoney = sd.getDepBalance().add(bo.getMoney(), MathContext.UNLIMITED);
    	if(newMoney.compareTo(sd.getDepAmt())==1)throw new CustomException("清退金额比押金金额大");
    	sd.setDepBalance(newMoney);
    	bo.setLastMoney(sd.getDepBalance());
    	bo.setDel(false);
    	bo.setCreateTime(new Date());
    	this.sysDepositBackRepository.save(bo);
    	if(sd.getDepMaxType()==0) {
			this.productHelpService.subtractMoney(bo.getDepPayaccountId(), sd.getProjId(), 1, bo.getMoney(),  sd.getId()+"("+bo.getId()+")已收取押金清退");
    	}else if(sd.getDepMaxType()==1) {
    		this.productHelpService.subtractMoney(bo.getDepPayaccountId(), sd.getProjId(), 1, bo.getMoney(),  sd.getId()+"("+bo.getId()+")已支付押金收回");
    	}else {
    		throw new CustomException("未知的类型");
    	}
    	this.sysDepositRepository.save(sd);
        return toAjax(1);
    }

    /**
     * 修改押金变更信息
     */
    @ApiOperation("修改押金变更信息")
    @PreAuthorize("@ss.hasPermi('system:SysDepositUpdate:edit')")
    @Log(title = "押金变更信息", businessType = BusinessType.UPDATE)
    @RepeatSubmit
    @PutMapping()
    @Transactional
    public AjaxResult<Void> edit(@Validated @RequestBody SysDepositBack bo) {
    	throw new CustomException("不允许修改");
    }

    /**
     * 删除押金变更信息
     */
    @ApiOperation("删除押金变更信息")
    @PreAuthorize("@ss.hasPermi('system:SysDepositUpdate:remove')")
    @Log(title = "押金变更信息" , businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    @Transactional
    public AjaxResult<Void> remove(@NotEmpty(message = "主键不能为空")
                                       @PathVariable Long[] ids) {
    	for(long id : ids) {
    		SysDepositBack sdb = this.sysDepositBackRepository.findById(id).get();
        	SysDeposit sd = this.sysDepositRepository.findById(sdb.getDepId()).get();
            if(!this.productHelpService.mayUse(sd.getProjId(), sdb.getDepTime()))throw new CustomException("项目已在指定时间已结账！不能增加！");
        	if(sd.getDepMaxType()==0) {
    			this.productHelpService.subtractMoney(sdb.getDepPayaccountId(), sd.getProjId(), 1, sdb.getMoney(), sd.getId()+"("+sdb.getId()+")已清退押金删除");
        	}else if(sd.getDepMaxType()==1) {
        		this.productHelpService.subtractMoney(sdb.getDepPayaccountId(), sd.getProjId(), 1, sdb.getMoney(),  sd.getId()+"("+sdb.getId()+")已收回押金删除");
        	}else {
        		throw new CustomException("未知的类型");
        	}
        	sd.setDepBalance(sd.getDepBalance().subtract(sdb.getMoney(), MathContext.UNLIMITED));
        	this.sysDepositBackRepository.delete(sdb);
    	}
        return toAjax(1);
    }
}
